package org.example.myleet.p636;

import java.util.*;

public class Solution {
    public int[] exclusiveTime(int n, List<String> logs) {
        //初始化各方法的模拟对象
        Fun[] functions = new Fun[n];
        for (int i = 0; i < n; ++i) {
            functions[i] = new Fun(1);
        }
        //解析日志并排序
        List<Log> logList = new ArrayList<>(logs.size());
        for (String l : logs) {
            logList.add(new Log(l));
        }
        logList.sort(Comparator.comparingInt(o -> o.time));
        //模拟调用栈，按照每一条日志模拟执行以及时间记录
        Deque<Fun> stack = new LinkedList<>();
        for (Log log : logList) {
            if ("start".equals(log.status)) {
                Fun peek = stack.peek();
                if (null != peek) {
                    if (peek.lastStart > -1) {
                        //如果栈中存有方法在执行，则记录此方法的占用时间
                        peek.spent += log.time - peek.lastStart;
                        //此方法被挂起，没有开始时间
                        peek.lastStart = -1;
                    }
                }
                //开始新的方法的时间记录，并入栈
                Fun function = functions[log.id];
                function.lastStart = log.time;
                stack.push(function);
            } else {
                //栈顶方法执行结束，记录消耗的时间
                Fun function = stack.pop();
                function.spent += log.time - function.lastStart + 1;
                //此方法执行结束，没有开始时间
                function.lastStart = -1;
                Fun peek = stack.peek();
                if (null != peek) {
                    //如果栈中存有方法在执行，则此方法会继续被执行，记录开始执行的时间
                    peek.lastStart = log.time + 1;
                }
            }
        }
        //输出结果
        int[] functionSpentArr = new int[n];
        for (int i = 0; i < n; ++i) {
            functionSpentArr[i] = functions[i].spent;
        }
        return functionSpentArr;
    }

    private

    static class Fun {
        int id;
        int spent;
        int lastStart;

        public Fun(int id) {
            this.id = id;
            this.spent = 0;
            this.lastStart = -1;
        }
    }

    static class Log {
        int id;
        String status;
        int time;

        public Log(String s) {
            String[] parts = s.split(":");
            id = Integer.parseInt(parts[0]);
            status = parts[1];
            time = Integer.parseInt(parts[2]);
        }
    }
}
